﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ReBasic.Model;

namespace ReBasic.Database
{
    public class ProBaseInterface
    {
        /// <summary>
        /// return Frequency of Occurrence for two concepts
        /// </summary>
        /// <param name="SuperConcept">Super-Concept</param>
        /// <param name="SubConcept">Sub-Concept</param>
        /// <returns></returns>
        public static int OccurFreq(string SuperConcept, string SubConcept)
        {
            int pix = ProBase.SupConDict[SuperConcept];
            int bix = ProBase.SubConDict[SubConcept];
            int stp = ProBase.SupIdxStart[pix];
            int edp = ProBase.SupIdxStart[pix + 1] - 1;
            int mid, t;
            while (stp <= edp)
            {
                mid = (stp + edp) / 2;
                t = ProBase.SupPool[mid].idx;
                if (t == bix)
                    return ProBase.SupPool[mid].freq;
                else if (t < bix)
                    stp = mid + 1;
                else
                    edp = mid - 1;
            }
            return 0;
        }

        /// <summary>
        /// return Frequency of Occurrence for two indices representing two concepts
        /// </summary>
        /// <param name="SupConIdx">Super-Concept index</param>
        /// <param name="SubConIdx">Sub-Concept index</param>
        /// <returns></returns>
        public static int OccurFreq(int SupConIdx, int SubConIdx)
        {
            int stp = ProBase.SupIdxStart[SupConIdx];
            int edp = ProBase.SupIdxStart[SupConIdx + 1] - 1;
            int mid, t;
            while (stp <= edp)
            {
                mid = (stp + edp) / 2;
                t = ProBase.SupPool[mid].idx;
                if (t == SubConIdx)
                    return ProBase.SupPool[mid].freq;
                else if (t < SubConIdx)
                    stp = mid + 1;
                else
                    edp = mid - 1;
            }
            return 0;
        }

        /// <summary>
        /// Return the Total Frequency for a string occured as a Super-Concept
        /// </summary>
        /// <param name="SuperConcept">Super-Concept</param>
        /// <returns></returns>
        public static int SupFreq(string SuperConcept)
        {
            return ProBase.SupSum[ProBase.SupConDict[SuperConcept]];
        }

        /// <summary>
        /// Return the Total Frequency for a index representing a string occurred as a Super-Concept
        /// </summary>
        /// <param name="SupConIdx">Super-Concept index</param>
        /// <returns></returns>
        public static int SupFreq(int SupConIdx)
        {
            return ProBase.SupSum[SupConIdx];
        }

        /// <summary>
        /// Return the Total Frequency for a string occured as a Sub-Concept
        /// </summary>
        /// <param name="SubConcept">Sub-Concept</param>
        /// <returns></returns>
        public static int SubFreq(string SubConcept)
        {
            return ProBase.SubSum[ProBase.SubConDict[SubConcept]];
        }

        /// <summary>
        /// Return the Total Frequency for a index representing a string occurred as a Sub-Concept
        /// </summary>
        /// <param name="SubConIdx">Sub-Concept index</param>
        /// <returns></returns>
        public static int SubFreq(int SubConIdx)
        {
            return ProBase.SubSum[SubConIdx];
        }

        /// <summary>
        /// Return the Total Count of classes for a Sub-Concept
        /// </summary>
        /// <param name="SubConcept">Sub-Concept</param>
        /// <returns></returns>
        public static int SubCount(string SubConcept)
        {
            return ProBase.SubCount[ProBase.SubConDict[SubConcept]];
        }

        /// <summary>
        /// Return the Total Count of classes for a index representing a Sub-Concept
        /// </summary>
        /// <param name="SubConIdx">Sub-Concept index</param>
        /// <returns></returns>
        public static int SubCount(int SubConIdx)
        {
            return ProBase.SubCount[SubConIdx];
        }

        /// <summary>
        /// return the Top-K sub-concept list for a Super-Concept
        /// </summary>
        /// <param name="SuperConcept">The Super-Concept</param>
        /// <param name="Top">The number of returned list</param>
        /// <returns>The list for indexed data</returns>
        public static List<IndexRelation> FindTopInSup(string SuperConcept, int Top)
        {
            if (Top == 0) 
                Top = 2147483647;
            List<IndexRelation> ret = new List<IndexRelation>();
            int pix = ProBase.SupConDict[SuperConcept];
            int fstp = ProBase.SupFreqStart[pix];
            while (fstp != -1 && Top-- > 0)
            {
                ret.Add(new IndexRelation(pix, 
                    ProBase.SupPool[fstp].idx, ProBase.SupPool[fstp].freq));
                fstp = ProBase.SupFreqList[fstp];
            }
            return ret;
        }

        public static List<IndexRelation> FindTopInSup(int sup_idx, int top)
        { 
            return FindTopInSup(ProBase.SupUhash[sup_idx], top);
        }

        /// <summary>
        /// return the Top-K super-concept list for a Sub-Concept
        /// </summary>
        /// <param name="SubConcept">The Sub-Concept</param>
        /// <param name="Top">The number of returned list</param>
        /// <returns>The list for indexed data</returns>
        public static List<IndexRelation> FindTopInSub(string SubConcept, int Top)
        { 
            if (Top == 0) 
                Top = 2147483647;
            List<IndexRelation> ret = new List<IndexRelation>();
            int bix = ProBase.SubConDict[SubConcept];
            int fstb = ProBase.SubFreqStart[bix];
            while (fstb != -1 && Top-- > 0)
            {
                ret.Add(new IndexRelation(ProBase.SubPool[fstb].idx, 
                    bix, ProBase.SubPool[fstb].freq));
                fstb = ProBase.SubFreqList[fstb];
            }
            return ret;
        }

        public static List<IndexRelation> FindTopInSub(int sub_idx, int top)
        { 
            return FindTopInSub(ProBase.SubUhash[sub_idx], top);
        }
    }
}
